<template>
	<div>nextticktest</div>
	<h3>nextTick的使用场景</h3>
	<div>场景一：如果要在created钩子函数中操作DOM需要放在Vue.nextTick()回调函数中执行；</div>

	<h3 ref="title">{{msg}}</h3>
	<div>场景二：当数据变化后，我们希望拿到修改数据后的DOM结构去做某些操作时也需要放到Vue.nextTick()回调函数中</div>
	<button @click="changeMsg">next tick Click</button>

	<h3>vue3通过proxy方式解决了对象添加新属性数据更新同步问题</h3>
	<div>name:{{tip.name}} age:{{tip.age}} </div>
	<button @click="changeTip">添加age属性</button>
	
	<h3>模拟nextTick原理</h3>
	<button @click="nextTickTest">next tick Click</button>
</template>

<script>
	import {
		ref,
		reactive
	} from 'vue'
	export default {
		setup() {
			var title = ref(null)
			return {
				title,
			}
		},
		data() {
			return {
				title: 'nextTick-异步执行任务模拟',
				msg: 'hello',
				tip: {
					name: 'xxx'
				},
			}
		},
		//nextTick的使用场景: 1.在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中
		created() {
			console.log('created');
			console.log(this.title)
			this.$nextTick(() => {
				console.log('created-nextTick');
				console.log(this.title)
			})
		},

		mounted() {
			// this.nextTickTest();

		},
		methods: {
			//nextTick 最核心的实现就是：拿一个队列存储所有要执行的任务，在下一个tick（异步）执行这些任务
			//进一步理解了 nextTick：将需要异步执行的任务收集起来在下一个 tick 依次执行他们
			nextTickTest() {
				let pending = false
				const tasks = []

				const flushCallbacks = () => {
					pending = false
					console.log('tasks.length', tasks.length)
					tasks.forEach(task => task())
					tasks.length = 0
				}
				const timerFunc = () => {
					Promise.resolve().then(flushCallbacks)
				}

				function nextTick(task) {
					tasks.push(task)
					console.log('pending', pending)
					if (!pending) {
						pending = true
						console.log('timerFunc')
						timerFunc()
					}
				}

				const task1 = () => console.log('1')
				const task2 = () => console.log('2')

				console.log('before===')
				nextTick(task1)
				nextTick(task2)
				nextTick(task1)
				nextTick(task2)
				nextTick(task1)
				console.log('after===')

			},

			changeMsg() {
				this.msg = 'changed'
				console.log('this.msg', this.msg)
				var title = this.title
				console.log('this.title', title.innerHTML) //顺序1：hello
				// DOM 还没有更新
				this.$nextTick(() => {
					// DOM 更新了
					console.log('this.title=$nextTick', this.title.innerHTML) //顺序3：changed
				})
				// 作为一个 Promise 使用
				this.$nextTick().then(() => {
					console.log('this.title=$nextTick', this.title.innerHTML) //顺序4：changed
				})
				console.log('this.title', title.innerHTML) //顺序2：hello
			},

			changeTip() {
				this.tip.age = '18'
				console.log('this.tip', this.tip)
			},

		},

	}
</script>

<style>
</style>
